package com.chat.zookeeper;



import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @Auther created by haoteng on 2019/08/20
 */
public class ZkUtil {

    private Logger logger = LoggerFactory.getLogger(ZkUtil.class);

    private static CountDownLatch downLatch = new CountDownLatch(1);

    private static ZooKeeper zooKeeper = null;

    private void initConnect() {
        synchronized (ZkUtil.class) {
            if (zooKeeper == null) {
                try {
                    zooKeeper = new ZooKeeper("127.0.0.1:2181", 50000, new ZkWatcher());
//                    zooKeeper.getSessionId()
                    downLatch.await();
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                    logger.error("初始化zk失败，检查zk服务");
                    throw new RuntimeException("连接zk失败");
                }
            }
        }
    }

    public String create(String path, String data, CreateMode createMode) {
        try {
            if (zooKeeper == null) {
                initConnect();
            }
            return zooKeeper.create(path, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException("写入zk失败");
        }
    }

    public Boolean exists(String path) {
        try {
            if (zooKeeper == null) {
                initConnect();
            }
            Stat stat = zooKeeper.exists(path, false);
            if (stat == null) {
                return false;
            } else {
                return true;
            }
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException("判断zk数据是否存在失败");
        }
    }

    public List<String> getChildren(String path, Watcher watcher) {
        try {
            if (zooKeeper == null) {
                initConnect();
            }
            return zooKeeper.getChildren(path, watcher);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException("获取zk子节点失败");
        }
    }

    public String getData(String path) {
        try {
            if (zooKeeper == null) {
                initConnect();
            }
            byte[] data = zooKeeper.getData(path, true, new Stat());
            return new String(data);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException("获取zk数据失败");
        }
    }

    public void setDate(String path, String data) {
        try {
            if (zooKeeper == null) {
                initConnect();
            }
            zooKeeper.setData(path, data.getBytes(), -1);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException("更改zk数据失败");
        }
    }

    public void delete(String path) {
        try {
            if (zooKeeper == null) {
                initConnect();
            }
            zooKeeper.delete(path, -1);
        } catch (InterruptedException | KeeperException e) {
            e.printStackTrace();
            throw new RuntimeException("删除zk数据失败");
        }
    }


    private class ZkWatcher implements Watcher {
        @Override
        public void process(WatchedEvent watchedEvent) {
            System.out.println("zk监听通知:" + watchedEvent.toString());
            downLatch.countDown();
        }
    }

}
